package com.SmartCare.service.impl.medicine;

import com.SmartCare.mapper.homeInfo.CareHomeDetailsMapper;
import com.SmartCare.mapper.medicine.MedicationFrequencyMapper;
import com.SmartCare.mapper.medicine.MedicationListMapper;
import com.SmartCare.mapper.medicine.MedicationMapper;
import com.SmartCare.mapper.medicine.MedicationRecordMapper;
import com.SmartCare.mapper.role.UserMapper;
import com.SmartCare.pojo.homeInfo.CareHomeDetails;
import com.SmartCare.pojo.medicine.Medication;
import com.SmartCare.pojo.medicine.MedicationFrequency;
import com.SmartCare.pojo.medicine.MedicationList;
import com.SmartCare.pojo.medicine.MedicationRecord;
import com.SmartCare.pojo.role.ElderlyInformation;
import com.SmartCare.pojo.role.User;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.SmartCare.common.enums.Constants;
import com.SmartCare.common.Result;
import com.SmartCare.common.dto.medicine.ManagerMedicationRecordDTO;
import com.SmartCare.common.exception.ServiceException;
import com.SmartCare.common.dto.medicine.MedicationRecordDTO;
import com.SmartCare.common.vo.medicine.MedicationListAndIdVo;
import com.SmartCare.service.medicine.MedicationRecordService;
import com.SmartCare.common.vo.medicine.MedicationRecordVo;
import com.SmartCare.service.role.ElderlyInformationService;
import com.SmartCare.utils.DateTimeUtils;
import com.SmartCare.utils.MedicationRecordTransToDTO;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务实现类
 */
@Service
public class MedicationRecordServiceImpl extends ServiceImpl<MedicationRecordMapper, MedicationRecord> implements MedicationRecordService {

    @Resource
    private MedicationListMapper medicationListMapper;
    @Resource
    private MedicationFrequencyMapper medicationFrequencyMapper;
    @Resource
    private MedicationRecordTransToDTO medicationRecordTransToDTO;
    @Autowired
    private ElderlyInformationService elderlyInformationService;
    @Autowired
    private MedicationRecordMapper mapper;
    @Resource
    private CareHomeDetailsMapper careHomeDetailsMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private MedicationMapper medicationMapper;


    @Override
    public Result addRecords(Long listId) {
        //判断今天是否生成过记录
        QueryWrapper<MedicationRecord> qw = new QueryWrapper<>();
        qw.eq("medication_list_id", listId);
        qw.orderByDesc("create_time");
        List<MedicationRecord> listByNum = list(qw);
        //获取今天的日期
        LocalDate today = LocalDate.now();
        if (listByNum.size() != 0) {
            //获取第一条记录的创建时间
            Date createTime = listByNum.get(0).getCreateTime();
            LocalDateTime createTimeLocal = createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            LocalDate createDate = createTimeLocal.toLocalDate();
            if (createDate.equals(today)) {
                return Result.success("今日已生成过该药单项的记录");
            }
        }
        //生成记录

        //先获取药单项
        MedicationList one = medicationListMapper.selectById(listId);
        //判空
        if (one == null) {
            throw new ServiceException(Constants.CODE_400, "不存在此id的药单项");
        }
        //检查药单项是否有用药频率
        MedicationFrequency frequency = medicationFrequencyMapper.selectById(one.getFrequencyId());
        if (frequency == null) {
            throw new ServiceException(Constants.CODE_400, "未设置该药单项的用药频率");
        }
        //获取用药时间
        String[] split = one.getTakeTime().split(";");

        //生成用药记录
        for (int i = 0; i < frequency.getValue(); i++) {
            MedicationRecord m = new MedicationRecord();
            m.setElderlyId(one.getElderlyId());
            m.setNurseId(one.getNurseId());
            m.setMedicationListId(listId);
            m.setListNum(one.getListNum());
            m.setStatus(0);
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
            try {
                Date date = sdf.parse(split[i]);
                Time time = new Time(date.getTime());
                m.setTime(time);
            } catch (ParseException e) {
                throw new ServiceException(Constants.CODE_400, "TakeTime属性格式有误");
            }
            //保存生成的记录
            save(m);
        }
        return Result.success();
    }

    @Override
    public Result updateStatus(Long id, Integer status) {
        //先判空
        MedicationRecord one = getById(id);
        if (one == null) {
            throw new ServiceException(Constants.CODE_400, "不存在此id的用药记录");
        }
        //添加id和状态
        UpdateWrapper<MedicationRecord> uw = new UpdateWrapper<>();
        uw.eq("id", id);
        uw.set("status", status);
        //修改更新时间
        if (status == 1) {
            uw.set("update_time", new Date());
        } else {
            uw.set("update_time", null);
        }
        //更新
        update(uw);
        return Result.success();
    }

    @Override
    public Result selectAllRecords(Long elderlyId) {
        //判空
        List<MedicationRecord> list = list(new QueryWrapper<MedicationRecord>().eq("elderly_id", elderlyId));
        List<MedicationRecordDTO> dtoList = new ArrayList<>();
        if (list.size() == 0) {
            throw new ServiceException(Constants.CODE_400, "不存在老人id为此的用药记录");
        }
        for (MedicationRecord record : list) {
            dtoList.add(medicationRecordTransToDTO.transToDTO(record));
        }
        dtoList = dtoList.stream().sorted(Comparator.comparing(MedicationRecordDTO::getCreateTime).reversed()).collect(Collectors.toList());
        //返回用药记录
        return Result.success(dtoList);
    }


    @Override
    public Result selectToday(Long elderlyId) {
        //判空
        QueryWrapper<MedicationRecord> qw = new QueryWrapper<>();
        qw.eq("elderly_id", elderlyId);
        List<MedicationRecord> list = list(qw);
        if (list.size() == 0) {
            throw new ServiceException(Constants.CODE_400, "不存在该老人的任何用药记录");
        }
        //获取今天的日期
        LocalDate today = LocalDate.now();
        //从中排除创建时间不在今天的用药记录
        list.removeIf(record -> {
            Date createTime = record.getCreateTime();
            LocalDateTime createTimeLocal = createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            LocalDate createDate = createTimeLocal.toLocalDate();
            return !createDate.equals(today);
        });
        List<MedicationRecordDTO> result = new ArrayList<>();
        //转成dto
        for (MedicationRecord record : list) {
            result.add(medicationRecordTransToDTO.transToDTO(record));
        }
        //返回
        return Result.success(result);
    }

    /**
     * 根据护工id查询用药记录表中的老人名称
     *
     * @param id
     * @return
     */
    @Override
    public Result getEldersById(Long id) {
        if (id == null) {
            return Result.error("未知错误，请重试");
        }
        LambdaQueryWrapper<MedicationRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MedicationRecord::getNurseId, id);
        queryWrapper.eq(MedicationRecord::getStatus, false);
        List<MedicationRecord> medicationRecords = list(queryWrapper);

        if (medicationRecords.isEmpty()) {
            return Result.success("今日无用药任务");
        }

        // 创建一个Set用于存储唯一的elderlyId值
        Set<Long> lists = new HashSet<>();
        medicationRecords.forEach((item) -> {
            lists.add(item.getElderlyId());
        });


        LambdaQueryWrapper<ElderlyInformation> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ElderlyInformation::getElderlyId, lists);
        List<ElderlyInformation> elderls = elderlyInformationService.list(wrapper);
        List<Map<Long, String>> res = new ArrayList<>();
        elderls.forEach((item) -> {
            Map<Long, String> map = new HashMap<>();
            map.put(item.getElderlyId(), item.getElderlyName());
            res.add(map);
        });

        return Result.success(res);
    }

    @Override
    public Result getMIds(Long elderId, Long nurseId) {
        if (elderId == null) {
            return Result.error("未知错误，请重试");
        }
        //time字段限制
        String[] times = DateTimeUtils.getStartAndEndTime();
        //日期字段限制
        LocalDateTime[] times1 = DateTimeUtils.getStartAndEndDateTime(0);

        LambdaQueryWrapper<MedicationRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MedicationRecord::getElderlyId, elderId);
        queryWrapper.eq(MedicationRecord::getNurseId, nurseId);
        queryWrapper.eq(MedicationRecord::getStatus, false);
        queryWrapper.between(MedicationRecord::getTime, times[0], times[1]);
        queryWrapper.between(MedicationRecord::getCreateTime, times1[0], times1[1]);
        List<MedicationRecord> medicationRecords = list(queryWrapper);

        List<MedicationListAndIdVo> vos = new ArrayList<>();
        medicationRecords.forEach((item) -> {
            MedicationListAndIdVo vo = new MedicationListAndIdVo();
            BeanUtils.copyProperties(item, vo);
            vos.add(vo);
        });
        return Result.success(vos);

    }

    /**
     * 查看服用情况
     */
    @Override

    public Result getDetails(List<Long> ids) {
        List<MedicationRecordVo> list = mapper.getNameAndId(ids);
        return Result.success(list);
    }

    @Override
    public Result generateTodayRecords() {
        //获取今天的日期
        LocalDate today = LocalDate.now();

        //构建查询条件
        QueryWrapper<MedicationList> qw = new QueryWrapper<>();
        qw.le("start_time", today);
        qw.ge("end_time", today);

        //查询数据库并获取符合条件的药单项列表
        List<MedicationList> list = medicationListMapper.selectList(qw);

        List<MedicationRecord> listByNum;

        //根据列表生成记录
        for (MedicationList medicationList : list) {

            //判断今天是否生成过记录
            QueryWrapper<MedicationRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("medication_list_id", medicationList.getId());
            queryWrapper.orderByDesc("create_time");
            listByNum = list(queryWrapper);
            if (listByNum.size() != 0) {
                //获取第一条记录的创建时间
                Date createTime = listByNum.get(0).getCreateTime();
                LocalDateTime createTimeLocal = createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                LocalDate createDate = createTimeLocal.toLocalDate();
                if (createDate.equals(today)) {
                    //今日已生成过此记录
                    continue;
                }
            }
            //生成记录

            //先获取药单项
            MedicationList one = medicationListMapper.selectById(medicationList.getId());
            //判空
            if (one == null) {
                //药单项不存在
                continue;
            }
            //检查药单项是否有用药频率
            MedicationFrequency frequency = medicationFrequencyMapper.selectById(one.getFrequencyId());
            if (frequency == null) {
                //未设置该药单项的用药频率
                continue;
            }
            //获取用药时间
            String[] split = one.getTakeTime().split(";");

            //生成用药记录
            for (int i = 0; i < frequency.getValue(); i++) {
                MedicationRecord m = new MedicationRecord();
                m.setElderlyId(one.getElderlyId());
                m.setNurseId(one.getNurseId());
                m.setMedicationListId(medicationList.getId());
                m.setListNum(one.getListNum());
                m.setStatus(0);
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                try {
                    Date date = sdf.parse(split[i]);
                    Time time = new Time(date.getTime());
                    m.setTime(time);
                } catch (ParseException e) {
                    e.printStackTrace();
                    continue;
                }
                //保存生成的记录
                save(m);
            }

        }

        return Result.success();
    }

    @Override
    public Result getPageRecords(String name, Integer pageSize, Integer pageNum, String keyword, String type) {
        //养老院判空
        CareHomeDetails careHome = careHomeDetailsMapper.selectOne(new QueryWrapper<CareHomeDetails>().eq("name", name));
        if (careHome == null) {
            return Result.error(Constants.CODE_400, "养老院不存在");
        }
        //获取本院老人id列表
        QueryWrapper<ElderlyInformation> elderQw = new QueryWrapper<>();
        elderQw.eq("current_care_home_id", careHome.getId());

        if (type.equals("elder")) {
            elderQw.like("elderly_name", keyword);
        }

        List<ElderlyInformation> elders = elderlyInformationService.list(elderQw);

        List<Long> elderIds = elders.stream().map(ElderlyInformation::getElderlyId).collect(Collectors.toList());

        //获取记录
        QueryWrapper<MedicationRecord> recordQw = new QueryWrapper<>();

        if (!type.equals("elder") && !type.equals("worker") && !type.equals("medication")) {
            recordQw.like(type, keyword);
        }


        if(elderIds.isEmpty()){
            recordQw.in("elderly_id", "0");
        }else{
            recordQw.in("elderly_id", elderIds);
        }

        //获取护工id列表
        if (type.equals("worker")) {
            QueryWrapper<User> userQw = new QueryWrapper<>();
            userQw.like("name", keyword);
            userQw.eq("care_home_name", name);
            userQw.eq("role", 1);
            List<User> users = userMapper.selectList(userQw);
            List<Long> userIds = users.stream().map(User::getUserId).collect(Collectors.toList());

            if(userIds.isEmpty()){
                recordQw.in("nurse_id", "0");
            }else{
                recordQw.in("nurse_id", userIds);
            }
        }

        //获取药品id列表
        if (type.equals("medication")) {
            //获取符合的药品的id数组
            QueryWrapper<Medication> medicationQw = new QueryWrapper<>();
            medicationQw.like("name", keyword);
            List<Long> mIds = medicationMapper.selectList(medicationQw).stream().map(Medication::getId).collect(Collectors.toList());
            //获取符合的药单的id数组
            QueryWrapper<MedicationList> listQw = new QueryWrapper<>();
            listQw.in("medication_id", mIds);
            List<Long> listIds = medicationListMapper.selectList(listQw).stream().map(MedicationList::getId).collect(Collectors.toList());
            //限制用药记录在符合条件下

            if(listIds.isEmpty()){
                recordQw.in("medication_list_id", "0");
            }else{
                recordQw.in("medication_list_id", listIds);
            }
        }

        //分页
        IPage<MedicationRecord> iPage = new Page<>(pageNum, pageSize);
        recordQw.orderByDesc("create_time");
        IPage<MedicationRecord> page = page(iPage, recordQw);

        // 获取符合条件的ApiLog记录

        List<MedicationRecord> list = page.getRecords();

        // 将ApiLog记录转换为ApiLogDTO
        List<MedicationRecordDTO> dtoList = new ArrayList<>();
        for (MedicationRecord mr : list) {
            dtoList.add(medicationRecordTransToDTO.transToDTO(mr));
        }

        // 创建新的IPage用于存放转换后的信息
        IPage<MedicationRecordDTO> dtoPage = new Page<>();
        dtoPage.setRecords(dtoList);
        dtoPage.setTotal(page.getTotal());
        return Result.success(dtoPage);
    }

    @Override
    public Result getRecordsData(String name) {
        //养老院判空
        CareHomeDetails careHome = careHomeDetailsMapper.selectOne(new QueryWrapper<CareHomeDetails>().eq("name", name));
        if (careHome == null) {
            return Result.error(Constants.CODE_400, "养老院不存在");
        }
        //获取本院所有用药记录
        QueryWrapper<ElderlyInformation> eqw = new QueryWrapper<>();
        eqw.eq("current_care_home_id", careHome.getId());

        //获取本院老人id数组
        List<Long> eIds = elderlyInformationService.list(eqw).stream().map(ElderlyInformation::getElderlyId).collect(Collectors.toList());
        //获取今天记录
        QueryWrapper<MedicationRecord> rQw = new QueryWrapper<>();
        List<MedicationRecord> todayRecords;
        if(eIds.isEmpty()){
            todayRecords = new ArrayList<>();
        }else{
            rQw.in("elderly_id", eIds);
            rQw.orderByDesc("create_time");

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String todayFormatted = dateFormat.format(new Date());
            // 设置create_time字段范围为今天
            rQw.ge("create_time", todayFormatted + " 00:00:00");
            rQw.le("create_time", todayFormatted + " 23:59:59");
            todayRecords = list(rQw);
        }
        ManagerMedicationRecordDTO dto = new ManagerMedicationRecordDTO();
        //今日待执行记录数
        dto.setNotYet(Long.valueOf(todayRecords.stream().filter(r -> r.getStatus() == 0).count()).intValue());
        //pages改成今日全部用药记录数
        dto.setCount(todayRecords.size());
        //current改成今日是否已生成记录
        dto.setTodays(todayRecords.size() != 0);
        return Result.success(dto);
    }

    @Override
    public void export(HttpServletResponse response, String name, Long id) {
        //养老院判空
        CareHomeDetails careHome = careHomeDetailsMapper.selectOne(new QueryWrapper<CareHomeDetails>().eq("name", name));
        if (careHome == null) {
            throw new ServiceException(Constants.CODE_400, "养老院不存在");
        }
        //获取本院老人id数组
        QueryWrapper<ElderlyInformation> eqw = new QueryWrapper<>();
        if (id == 0) {
            //id为0，导出全院的信息
            eqw.eq("current_care_home_id", careHome.getId());
        } else {
            //id不为0，导出id代表的老人的所有信息
            eqw.eq("elderly_id", id);
        }
        List<Long> eIds = elderlyInformationService.list(eqw).stream().map(ElderlyInformation::getElderlyId).collect(Collectors.toList());

        //查询药品数据
        List<MedicationRecord> records = list(new QueryWrapper<MedicationRecord>().in("elderly_id", eIds));
        List<MedicationRecordDTO> dtos = new ArrayList<>();
        //转换成dto
        for (MedicationRecord record : records) {
            dtos.add(medicationRecordTransToDTO.transToDTO(record));
        }
        //格式化显示时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");
        //创建一个新的Excel工作簿
        try (Workbook workbook = new XSSFWorkbook()) {
            // 创建一个工作表
            Sheet sheet = workbook.createSheet("MedicationRecords");

            //创建标题行
            Row headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("记录生成日期");
            headerRow.createCell(1).setCellValue("用药老人");
            headerRow.createCell(2).setCellValue("服用药品");
            headerRow.createCell(3).setCellValue("服用剂量");
            headerRow.createCell(4).setCellValue("预定服用时间");
            headerRow.createCell(5).setCellValue("实际服用时间");
            headerRow.createCell(6).setCellValue("负责护工");
            headerRow.createCell(7).setCellValue("服用状态");

            //填充数据行
            int rowNum = 1;
            for (MedicationRecordDTO dto : dtos) {
                Row dataRow = sheet.createRow(rowNum++);
                if (dto.getCreateTime() != null) {
                    dataRow.createCell(0).setCellValue(sdf.format(dto.getCreateTime()));
                }
                if (dto.getElder() != null) {
                    dataRow.createCell(1).setCellValue(dto.getElder().getElderlyName());
                }
                if (dto.getMedicationList() != null) {
                    dataRow.createCell(2).setCellValue(dto.getMedicationList().getMedication().getName());
                }
                if (dto.getMedicationList() != null) {
                    dataRow.createCell(3).setCellValue(dto.getMedicationList().getDosage() + dto.getMedicationList().getUnit());
                }
                if (dto.getTime() != null) {
                    dataRow.createCell(4).setCellValue(sdfTime.format(dto.getTime()));
                }
                if (dto.getUpdateTime() != null) {
                    dataRow.createCell(5).setCellValue(sdf.format(dto.getUpdateTime()));
                }
                if (dto.getNurse() != null) {
                    dataRow.createCell(6).setCellValue(dto.getNurse().getName());
                }
                if (dto.getStatus() != null) {
                    dataRow.createCell(7).setCellValue(dto.getStatus() == 1 ? "已服用" : "未服用");
                }
            }
            //设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=MedicationRecordsExport.xlsx");

            // 将工作簿内容写入响应输出流
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
